package com.example.admin.service.imp;

import com.alibaba.fastjson.JSONObject;
import com.example.admin.Dto.*;
import com.example.admin.Vo.CheckInItem;
import com.example.admin.Vo.CheckInVo;
import com.example.admin.bean.*;
import com.example.admin.constants.CheckInConstants;
import com.example.admin.constants.RetreatConstant;
import com.example.admin.mapper.*;
import com.example.admin.service.CheckInservice;
import com.example.admin.service.WorkStremService;
import com.example.admin.utils.CodeUtil;
import com.example.admin.utils.StringUtils;
import com.example.admin.utils.UserThreadLocal;
import org.activiti.engine.HistoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricVariableInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;

@Service
@Transactional
public class ImpCheckIn implements CheckInservice {
    @Autowired
    CheckInmapper checkInmapper;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    AccraditationRecordmapper accraditationRecordmapper;
    @Autowired
    WorkStremService workStremService;
    @Autowired
    Eldermapper eldermapper;
    @Autowired
    Usermapper usermapper;
    @Autowired
    TaskService taskService;
    @Autowired
    HistoryService historyService;
    @Autowired
    NursingProjectmapper nursingProjectmapper;

    @Override
    @Transactional
    public void createCheckIn(CheckInDto checkInDto) {
        if (StringUtils.isNotEmpty(checkInDto.getTaskid())){
            workStremService.complete(checkInDto.getTaskid(), "驳回任务重新提交",null);
            String subject = UserThreadLocal.getSubject();
            LoginUserDetails loginUserDetails = JSONObject.parseObject(subject, LoginUserDetails.class);
            Long user1 = workStremService.findguwen(checkInDto.getTaskid(), "user1");
            Long checkid =  checkInmapper.findcheckidbydidcard(checkInDto.getElderDto().getIdCardNo());
            String name  = usermapper.findbyid(user1);
            AccraditationRecord accraditationRecord = AccraditationRecord.builder()
                    .opinion("驳回任务重新提交")
                    .type(3)
                    .approverId(loginUserDetails.getId())
                    .approverName(loginUserDetails.getRealName())
                    .approverNameRole("养老顾问")
                    .nextApproverId(user1)
                    .nextApprover(name)
                    .nextApproverRole("护理主管")
                    .bussniessId("业务id:"+checkid)
                    .currentStep("养老顾问" + loginUserDetails.getNickName() + "重新提交表单")
                    .nextStep("护理主管" + name + "审批表单")
                    .auditStatus(1)
                    .stepNo(1)
                    .handleType(0)
                    .build();
            accraditationRecordmapper.saveaccraditationrecord(accraditationRecord);
        }else {
            //1.检查老人是否已经提交申请，根据身份证和手机号码判断
            Integer checkisexit = checkInmapper.checkisexit(checkInDto.getElderDto());
            if (checkisexit > 0) {
                throw new RuntimeException("该老人已经提交申请");
            }
            //图片设置
            String url1 = checkInDto.getUrl1();
            if (StringUtils.isEmpty(url1)) {
                System.out.println("请设置近期照片");
            }
            String url2 = checkInDto.getUrl2();
            if (StringUtils.isEmpty(url2)) {
                System.out.println("请设置身份证正面");
            }
            String url3 = checkInDto.getUrl3();
            if (StringUtils.isEmpty(url3)) {
                System.out.println("请设置身份证反面");
            }
            ElderDto elderDto = checkInDto.getElderDto();
            elderDto.setImage(url1 + ":" + url2 + ":" + url3);
            //年龄
            String otherApplyInfo = checkInDto.getOtherApplyInfo();
            ElderDto copy = JSONObject.parseObject(otherApplyInfo, ElderDto.class);
            elderDto.setAge(copy.getAge());
            //性别
            elderDto.setSex(copy.getSex());
            //状态
            elderDto.setStatus(ElderDto.ElderStatus.CHECK_IN.getCode());
            //2.保存老人信息
            checkInmapper.saveelder(elderDto);
            //3.保存入住信息
            CheckIn checkIn = new CheckIn();
            String code = CodeUtil.generateCode(CheckInConstants.CHECK_IN_PREFIX_RZ, redisTemplate, 0);
            checkIn.setCheckInCode(code);
            checkIn.setTitle(elderDto.getName() + "的入住申请");
            checkIn.setElderId(elderDto.getId());
            String subject = UserThreadLocal.getSubject();
            LoginUserDetails loginUserDetails = JSONObject.parseObject(subject, LoginUserDetails.class);
            checkIn.setCounselor(loginUserDetails.getRealName());
            checkIn.setApplicat(loginUserDetails.getRealName());
            checkIn.setDeptNo(loginUserDetails.getDeptNo());
            checkIn.setApplicatId(loginUserDetails.getId());
            checkIn.setFlowStatus(CheckIn.FlowStatus.APPLY.getCode());
            checkIn.setStatus(CheckIn.Status.APPLICATION.getCode());
            checkIn.setOtherApplyInfo(checkInDto.getOtherApplyInfo());
            checkInmapper.savacheckin(checkIn);
            //4.准备流程变量
            HashMap<String, Object> maps = new HashMap<>();
////        user0:养老顾问第一个员工
            maps.put("user0", loginUserDetails.getId());
////        user1:护理部门主管，第二个员工
            User user1 = checkInmapper.finduserbydept(RetreatConstant.NURSING_DEPT_CODE);
            maps.put("user1", user1.getId());
//          user2:：院长，第三个员工
            User user2 = checkInmapper.finduserbydept(RetreatConstant.DEAN_OFFICE_DEPT_CODE);
            maps.put("user2", user2.getId());
//        user3:养老顾问第四个员工
            maps.put("user3", loginUserDetails.getId());
//        ser4：法务第五个员工
            User user4 = checkInmapper.finduserbydept(RetreatConstant.LEGAL_DEPT_CODE);
            maps.put("user4", user4.getId());
//        设置activity的全局变量
//        设置单据编号
            maps.put("code", code);
//        设置单据类型
            maps.put("type", 3);
//        设置流程状态
            maps.put("status", 1);
//        设置checkin主键
            maps.put("checkInId", checkIn.getId());
//        设置title
            maps.put("title", checkIn.getTitle());
//        设置申请人
            maps.put("applicat", checkIn.getApplicat());
            //业务id
            String bussniessId = "业务id:" + checkIn.getId();

            //    保存checkin审核记录
            AccraditationRecord accraditationRecord = AccraditationRecord.builder()
                    .opinion("审核自动通过")
                    .type(3)
                    .approverId(loginUserDetails.getId())
                    .approverName(loginUserDetails.getRealName())
                    .approverNameRole("养老顾问")
                    .nextApproverId(user1.getId())
                    .nextApprover(user1.getRealName())
                    .nextApproverRole("护理部门主管")
                    .bussniessId(bussniessId)
                    .currentStep("养老顾问" + loginUserDetails.getNickName() + "提交表单")
                    .nextStep("护理部门主管" + user1.getRealName() + "审核")
                    .auditStatus(1)
                    .stepNo(1)
                    .handleType(0)
                    .build();

            accraditationRecordmapper.saveaccraditationrecord(accraditationRecord);
            //开启任务流,提交任务到下一个阶段
            workStremService.startprocess("Process_1", bussniessId, maps);
        }

    }

    @Override
    public CheckInVo checkIndetail(String assigneeid, String code, Integer flowStatus, String taskid) {
        CheckInVo checkInVo = new CheckInVo();
//    封装vo里面的checkIn
        CheckIn dbcheckIn = checkInmapper.findcheckinbycode(code);
        CheckInItem checkIn = new CheckInItem();
        BeanUtils.copyProperties(dbcheckIn, checkIn);
        checkInVo.setCheckIn(checkIn);
        //给vo里面的checkin里面老人信息赋值
        ElderDto elderdto = eldermapper.findelderbyid(dbcheckIn.getElderId());
        checkIn.setElderDto(elderdto);

        //查询历史审批记录
       String keys =  "业务id:" + checkIn.getId();
        List<AccraditationRecord> Record =
                accraditationRecordmapper.findaccraditationrecordbybussniessid("业务id:" + checkIn.getId());
        checkInVo.setAccraditationRecords(Record);
        checkInVo.setType(CheckInConstants.CHECK_IN_PREFIX_RZ);
        checkInVo.setNextApprover(Record.get(Record.size() - 1).getNextApprover());
        return checkInVo;

    }

    @Override
    public void checkInReview(CheckInReviewDto checkInReviewDto) {
        // 第一步更新checkin表单
        CheckIn checkIn = new CheckIn();
        checkIn.setId(checkInReviewDto.getId());
        checkIn.setFlowStatus(CheckIn.FlowStatus.REVIEW.getCode());
        checkIn.setReviewInfo(JSONObject.toJSONString(checkInReviewDto));
        checkInmapper.updatacheckin(checkIn);
        //保存中间表
        String subject = UserThreadLocal.getSubject();
        LoginUserDetails loginUserDetails = JSONObject.parseObject(subject, LoginUserDetails.class);
        User user2 = checkInmapper.finduserbydept(RetreatConstant.DEAN_OFFICE_DEPT_CODE);
        AccraditationRecord accraditationRecord = AccraditationRecord.builder()
                .opinion("审核自动通过")
                .type(3)
                .approverId(loginUserDetails.getId())
                .approverName(loginUserDetails.getRealName())
                .approverNameRole("护理部门主管")
                .nextApproverId(user2.getId())
                .nextApprover(user2.getRealName())
                .nextApproverRole("院长")
                .bussniessId("业务id:"+checkIn.getId())
                .currentStep("护理部长" + loginUserDetails.getNickName() + "提交表单")
                .nextStep("院长" + user2.getRealName() + "审核")
                .auditStatus(1)
                .stepNo(1)
                .handleType(0)
                .build();
        accraditationRecordmapper.saveaccraditationrecord(accraditationRecord);
        //推进任务
        workStremService.complete(checkInReviewDto.getTaskId(),"护理主管通过审核",null);
    }

    @Override
    public void checkSubmit(Long id, String message, String taskId) {
        //第一步将checkin表单修改
        CheckIn checkIn = new CheckIn();
        checkIn.setId(id);
        checkIn.setFlowStatus(CheckIn.FlowStatus.APPROVAL.getCode());
        checkInmapper.updatacheckin(checkIn);
        //保存中间表
        String subject = UserThreadLocal.getSubject();
        LoginUserDetails loginUserDetails = JSONObject.parseObject(subject, LoginUserDetails.class);
        //寻找顾问来填充院长的下一级
        Long user0id = workStremService.findguwen(taskId, "user0");

        String name = usermapper.findbyid(user0id);
        AccraditationRecord accraditationRecord = AccraditationRecord.builder()
                .opinion("审核自动通过")
                .type(3)
                .approverId(loginUserDetails.getId())
                .approverName(loginUserDetails.getRealName())
                .approverNameRole("院长")
                .nextApproverId(user0id)
                .nextApprover(name)
                .nextApproverRole("护理顾问")
                .bussniessId("业务id:"+checkIn.getId())
                .currentStep("院长" + loginUserDetails.getNickName() + "审批表单")
                .nextStep("护理顾问" + name + "分配床位")
                .auditStatus(1)
                .stepNo(1)
                .handleType(0)
                .build();
        accraditationRecordmapper.saveaccraditationrecord(accraditationRecord);
        //推进任务
        workStremService.complete(taskId,message,1);
    }

    @Override
    public void checkReject(Long id, String message, String taskId) {
        //更新checkin表
        CheckIn checkIn = new CheckIn();
        checkIn.setId(id);
        checkIn.setFlowStatus(CheckIn.FlowStatus.APPROVAL.getCode());
        checkIn.setStatus(CheckIn.Status.CLOSED.getCode());
        checkInmapper.updatacheckin(checkIn);
        //保存中间表
        String subject = UserThreadLocal.getSubject();
        LoginUserDetails loginUserDetails = JSONObject.parseObject(subject, LoginUserDetails.class);
        AccraditationRecord accraditationRecord = AccraditationRecord.builder()
                .opinion("审核自动通过")
                .type(3)
                .approverId(loginUserDetails.getId())
                .approverName(loginUserDetails.getRealName())
                .approverNameRole("院长")
                .bussniessId("业务id:"+checkIn.getId())
                .currentStep("院长" + loginUserDetails.getNickName() + "审批表单")
                .auditStatus(2)
                .stepNo(1)
                .handleType(0)
                .build();
        accraditationRecordmapper.saveaccraditationrecord(accraditationRecord);
        //推进任务
        workStremService.complete(taskId,message,2);
    }

    @Override
    public void rebut(Long id, String message, String taskId) {
        //驳回更新checkin表
        CheckIn checkIn = new CheckIn();
        checkIn.setId(id);
        checkIn.setFlowStatus(CheckIn.FlowStatus.APPLY.getCode());
        checkInmapper.updatacheckin(checkIn);
        //生成中间表格
        String subject = UserThreadLocal.getSubject();
        LoginUserDetails loginUserDetails = JSONObject.parseObject(subject, LoginUserDetails.class);
        Long user1 = workStremService.findguwen(taskId, "user1");

        String name  = usermapper.findbyid(user1);
        AccraditationRecord accraditationRecord = AccraditationRecord.builder()
                .opinion(message)
                .type(3)
                .approverId(loginUserDetails.getId())
                .approverName(loginUserDetails.getRealName())
                .approverNameRole("院长")
                .nextApproverId(user1)
                .nextApprover(name)
                .nextApproverRole("护理主管")
                .bussniessId("业务id:"+checkIn.getId())
                .currentStep("院长" + loginUserDetails.getNickName() + "审批表单")
                .nextStep("护理主管" + name + "审批表单")
                .auditStatus(3)
                .stepNo(1)
                .handleType(0)
                .build();
        accraditationRecordmapper.saveaccraditationrecord(accraditationRecord);
        //推进任务
        workStremService.complete(taskId,message,3);
    }

    @Override
    public void checkinconfig(CheckInConfigDto checkInConfigDto) {
        //保存选配信息到表中
        CheckInConfig checkInConfig = new CheckInConfig();
        BeanUtils.copyProperties(checkInConfigDto,checkInConfig);
        String subject = UserThreadLocal.getSubject();
        LoginUserDetails loginUserDetails = JSONObject.parseObject(subject, LoginUserDetails.class);
        checkInConfig.setCreateBy(loginUserDetails.getId());
        checkInmapper.savecheckinconfig(checkInConfig);
        //更新老人表
        Elder elder = new Elder();
        elder.setId(checkInConfigDto.getElderId());
        elder.setBedId((checkInConfigDto.getBedNo()));
        elder.setBedNumber(checkInConfigDto.getBedNumber());
        eldermapper.updatacheckinconfig(elder);
        //更新床位表
        Bed bed = new Bed();
        bed.setBedNumber(checkInConfigDto.getBedNumber());
        bed.setBedStatus(2);
        checkInmapper.updatabed(bed);
        //更新checkin表单
        CheckIn checkIn = new CheckIn();
        checkIn.setId(checkInConfigDto.getCheckInId());
        checkIn.setCheckInTime(checkInConfigDto.getCheckInStartTime());
        checkIn.setFlowStatus(3);
        checkIn.setStatus(1);
        checkInmapper.updataconfig(checkIn);

        //保存中间表
//        Long user3 = workStremService.findguwen(checkInConfigDto.getTaskId(), "user3");
//        String name = usermapper.findbyid(user3);
        AccraditationRecord accraditationRecord = AccraditationRecord.builder()
                .opinion("养老顾问选配完成")
                .type(3)
                .approverId(loginUserDetails.getId())
                .approverName(loginUserDetails.getRealName())
                .approverNameRole("养老顾问")
                .nextApproverId(Long.parseLong("20"))
                .nextApprover("")
                .nextApproverRole("法务")
                .bussniessId("业务id:"+checkIn.getId())
                .currentStep("养老顾问" + loginUserDetails.getNickName() + "选配")
                .nextStep("法务签合同")
                .auditStatus(1)
                .stepNo(1)
                .handleType(0)
                .build();
        accraditationRecordmapper.saveaccraditationrecord(accraditationRecord);
        //推进下一个流程
        workStremService.complete(checkInConfigDto.getTaskId(), "养老顾问选配完成",null);
    }

    @Override
    public void sign(SignDto signDto) {
        //生成合同表
        Contract contract = new Contract();
        BeanUtils.copyProperties(signDto,contract);
        String code = CodeUtil.generateCode("HT", redisTemplate, 0);
        contract.setContractNo(code);
        contract.setStatus(1);
        String subject = UserThreadLocal.getSubject();
        LoginUserDetails loginUserDetails = JSONObject.parseObject(subject, LoginUserDetails.class);
        contract.setCreateBy(loginUserDetails.getId());
        checkInmapper.savacontract(contract);
        //修改checkIn表
        CheckIn checkIn = new CheckIn();
        checkIn.setId(signDto.getCheckInId());
        checkIn.setFlowStatus(CheckIn.FlowStatus.SIGN.getCode());
        checkIn.setStatus(CheckIn.Status.FINISHED.getCode());
        //生成护理任务
       List<NursingProject> projectlist =  nursingProjectmapper.maketask(signDto.getCheckInId());
      Long elderid =  checkInmapper.findelder(signDto.getCheckInId());
        for (NursingProject nursingProject : projectlist) {
            NursingTask nursingTask = new NursingTask();
            nursingTask.setElderId(elderid);
            nursingTask.setProjectId(nursingProject.getId());
            nursingTask.setTaskType(2L);
            nursingTask.setRelNo(code);
            checkInmapper.savenursingtask(nursingTask);
        }
        //更新老人的入住状态
        Elder elder = new Elder();
        elder.setId(elderid);
        elder.setStatus(1);
        checkInmapper.fixelderstatus(elder);
        //保存历史记录
        AccraditationRecord accraditationRecord = AccraditationRecord.builder()
                .opinion("法务完成签约")
                .type(3)
                .approverId(loginUserDetails.getId())
                .approverName(loginUserDetails.getRealName())
                .approverNameRole("法务")
                .bussniessId("业务id:"+checkIn.getId())
                .currentStep("法务" + loginUserDetails.getNickName() + "完成签约")
                .auditStatus(1)
                .stepNo(1)
                .handleType(0)
                .build();
        accraditationRecordmapper.saveaccraditationrecord(accraditationRecord);
        //结束任务
        workStremService.complete(signDto.getTaskId(),"法务完成签约",null);
    }



}